package org.itstack.demo.design.service;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.itstack.demo.design.AuthInfo;
import org.itstack.demo.design.client.HandlerClient;
import org.itstack.demo.design.entity.ProductCheckHandlerConfig;
import org.itstack.demo.design.entity.ProductVO;
import org.itstack.demo.design.handler.AbstractCheckHandler;

import java.util.Map;
import java.util.Objects;

@Slf4j
public class ProductService {

    public AuthInfo createProduct(ProductVO productVO){
        AuthInfo result = this.paramCheck(productVO);
        if (!result.isSuccess()){
            return result;
        }

        return this.saveProduct(productVO);
    }

    private AuthInfo saveProduct(ProductVO productVO) {
        log.info("成功创建产品!");
        return AuthInfo.success("成功创建产品!");
    }

    /**
     * 通过传递一个处理器链路，来校验参数
     * @param productVO
     * @return
     */
    private AuthInfo paramCheck(ProductVO productVO) {
        // 1. 首先获取链路信息（配置信息）
        ProductCheckHandlerConfig config = this.getHandlerConfig();

        // 2. 获取处理器
        AbstractCheckHandler handler = this.getHandler(config);

        // 3. 调用责任链
        assert handler != null;
        AuthInfo authInfo = HandlerClient.executeChain(handler, productVO);
        if (!authInfo.isSuccess()){
            log.error("创建商品失败....");
            return authInfo;
        }

        return AuthInfo.success("创建商品成功!");
    }

    /**
     * 递归构建成责任链
     * @param config
     * @return
     */
    private AbstractCheckHandler getHandler(ProductCheckHandlerConfig config) {
        if (Objects.isNull(config)){
            return null;
        }

        if (StringUtils.isBlank(config.getHandlerName())){
            return null;
        }

        Map<String, AbstractCheckHandler> handlerMap = HandlerClient.checkHandlerMap;
        AbstractCheckHandler handler = handlerMap.get(config.getHandlerName());
        if (Objects.isNull(handler)){
            return null;
        }

        handler.setConfig(config);
        handler.setNextHandler(this.getHandler(config.getNext()));
        return handler;
    }

    /**
     * 获取处理器配置类对象，配置类保存了链上各个处理器的上下级节点配置
     * @return
     */
    private ProductCheckHandlerConfig getHandlerConfig() {
        String configString = "{\"handlerName\":\"空值校验处理器\",\"down\":false,\"next\":{\"handlerName\":\"库存校验处理器\",\"down\":true,\"next\":{\"handlerName\":\"价格校验处理器\",\"down\":false,\"next\":null}}}";
        return JSONObject.parseObject(configString, ProductCheckHandlerConfig.class);
    }
}
